#include <cstring>
#include <iostream>
#include <sys/epoll.h>
#include <thread>
#include <unistd.h>

int main()
{
    int fd[2]; // 1. 创建管道
    pipe(fd);  // fd[0]读端  fd[1]写端

    int         epfd = epoll_create1(0); // 2. 创建epoll实例
    epoll_event ev_in{};
    ev_in.events  = EPOLLIN; // 关注“可读”
    ev_in.data.fd = fd[0];   // 把读端fd挂进去
    epoll_ctl(epfd, EPOLL_CTL_ADD, fd[0], &ev_in);

    epoll_event evs[4]; // 3. 事件“托盘”

    // 4. 启动一个线程往管道写数据，模拟“数据到达”
    std::thread t([w = fd[1]] {
        for (int i = 0; i < 3; ++i)
        {
            sleep(1);
            const char *s = "hello\n";
            write(w, s, strlen(s));
            std::cout << "[thread] write -> pipe\n";
        }
    });

    // 5. 主线程：epoll_wait 循环
    for (int round = 0; round < 3; ++round)
    {
        int n = epoll_wait(epfd, evs, 4, -1); // 阻塞等
        std::cout << "[epoll ] returned " << n << " ready fd(s)\n";
        for (int i = 0; i < n; ++i)
        {
            int      ready_fd = evs[i].data.fd;
            uint32_t events   = evs[i].events;
            std::cout << "       fd=" << ready_fd << " events=" << events << '\n';
            if (events & EPOLLIN)
            {
                char buf[32];
                int  sz = read(ready_fd, buf, sizeof(buf) - 1);
                buf[sz] = 0;
                std::cout << "       read: " << buf;
            }
        }
    }

    t.join();
    close(fd[0]);
    close(fd[1]);
    close(epfd);
}